﻿


//////////////////////////////////////////////////////////////////////////
/// 头文件
//////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "utlist.h"

//////////////////////////////////////////////////////////////////////////
/// 数据类型和全局变量定义
//////////////////////////////////////////////////////////////////////////
enum log_group_t _log_group;
enum log_level_t _log_level;
static enum log_level_t _log_lvl = LOG_LVL_DEFAULT;

static thrd_task_t _in_task; // 任务输入队列
static thrd_task_t _out_task;// 任务输出队列
static pthread_t tid;//线程ID

static bool stop_flg = false;//线程退出标志

/************************************************************************/
/* 客户端列表定义                                                       */
/************************************************************************/
// Describes listening socket, or socket which was accept()-ed by the master
// thread and queued for future handling by the worker thread.
typedef struct socket
{
    SOCKET sock;          // Listening socket
    union usa lsa;        // Local socket address
    union usa rsa;        // Remote socket address
} socket_t;


//客户端定义
typedef struct client_info
{
    session_t id;                        //ID
    bool recv;
    enum log_level_t lvl;
    socket_t sock;
    uint8_t  data[COMM_DATA_MAX_SIZE * 2];
    uint32_t len;
    uint8_t  send_data[COMM_DATA_MAX_SIZE * 2];
    uint32_t send_len;
    bool     stop;
    struct client_info *next;
} client_info_t;

// 维护客户端的链表
static client_info_t *client_list_hdr = NULL;
static uint32_t client_id = 0;
static socket_t listening_sock;//服务器监听socket
static uint32_t listening_sock_num = 0;//服务器监听socket

/************************************************************************/
/* 日志数据定义                                                         */
/************************************************************************/
static UT_array* log_queue;//输入队列
static FILE *log_fp;//日志文件的操作符
static pthread_mutex_t log_mutex;//日志模块的互斥量

/************************************************************************/
/* 内部通讯数据定义                                                     */
/************************************************************************/
typedef struct thrd_info
{
    bool valid;
    char name[5];//线程名
    task_addr_t addr;//线程地址
    thrd_ctl_list_node_t *ctl_list_hdr;//接受的命令队列
    thrd_task_t *_in; //线程输入队列
    thrd_task_t *_out; //线程输出队列
    pthread_cond_t *_in_cond; //输入条件变量

    unsigned int num_in;//输入数据包数量
    unsigned int num_out;//输出数据包数量

    struct thrd_info * next;
} thrd_info_t;

//用于记录线程的信息
static thrd_info_t *thrd_info_hdr = NULL;
static pthread_mutex_t _thrd_info_mutex;//线程互斥量

//////////////////////////////////////////////////////////////////////////
/// 函数声明
//////////////////////////////////////////////////////////////////////////
/************************************************************************/
/* 客户端列表维护                                                       */
/************************************************************************/
static uint32_t client_list_add(client_info_t *pclient);
static void client_list_del(session_t id);
static client_info_t *client_list_get(client_info_t *pclient, session_t cid);
static uint32_t client_list_len();
static uint32_t client_list_update(client_info_t *pclient, session_t cid);
static uint32_t client_list_update_recv(session_t cid, bool flg);
static uint32_t client_list_update_log_level(session_t cid, log_level_t lvl);
/************************************************************************/
/* 日志模块                                                             */
/************************************************************************/
static void log_to_file(log_entry_t * plog);
static log_entry_t * log_assembly(enum log_group_t group, enum log_level_t level, log_entry_t * plog, int8_t *log_data);
void log_new(enum log_group_t group, enum log_level_t level, int8_t * log);
static void task_log_handler(thrd_task_entry_t *ptask);

//////////////////////////////////////////////////////////////////////////
// 函数实现
//////////////////////////////////////////////////////////////////////////

/************************************************************************/
/* 客户端列表维护                                                       */
/************************************************************************/

/**
 * @brief     添加一个新的客户端
 * @param [in]  
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
static uint32_t client_list_add(client_info_t *pclient)
{
    client_info_t *ptr = NULL;

    if(pclient == NULL)
    {
        // TODO:返回错误——参数错误
        return ERR_ARG;
    }
    ptr = (client_info_t *)CALLOC(1, sizeof(client_info_t));
    if(ptr == NULL)
    {
        // TODO:返回错误——分配内存错误
        return ERR_NO_MEM;
    }
    if(client_id == 0)//ID从1开始
    {
        client_id = 1;
    }
    pclient->id =  client_id ++;
    pclient->recv = false;
    pclient->lvl = LOG_LVL_DEFAULT;
    MEMCPY(ptr, pclient, sizeof(client_info_t));
    LL_APPEND(client_list_hdr, ptr);

    return ERR_NULL;
}

/**
 * @brief     删除一个客户端
 * @param [in]  id:客户端ID
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
static void client_list_del(session_t id)
{
    client_info_t *ptr = NULL, *tmp = NULL;

    if(client_list_hdr == NULL)
    {
        // TODO:返回错误——参数错误
        return;
    }
    // 查找符合条件的条目并删除和释放
    LL_FOREACH_SAFE(client_list_hdr, ptr, tmp)
    {
        if(ptr->id == id)
        {
            LL_DELETE(client_list_hdr, ptr);
            FREE(ptr);
            break;
        }
    }

    return ;
}
/**
 * @brief     获取客户端
 * @param [in]  
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
static client_info_t *client_list_get(client_info_t *pclient, session_t cid)
{
    client_info_t *ptr = NULL, *tmp = NULL;

    if((client_list_hdr == NULL) || (pclient == NULL))
    {
        // TODO:返回错误——参数错误
        return NULL;
    }
    // 查找符合条件的条目
    LL_SEARCH_SCALAR(client_list_hdr, ptr, id, cid);
    if(ptr)
    {
        MEMCPY(pclient, ptr, sizeof(client_info_t));
        return pclient;
    }

    //LL_FOREACH_SAFE(client_list_hdr, ptr, tmp)
    //{
    //    if(ptr->id == id)
    //    {
    //        MEMCPY(pclient, ptr, sizeof(client_info_t));
    //        return pclient;
    //    }
    //}

    return NULL;
}
/**
 * @brief     获取客户端列表的长度
 * @param [in]  
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
static uint32_t client_list_len()
{
    int n =0;
    client_info_t *ptr = NULL, *tmp = NULL;

    // 查找符合条件的条目
    LL_FOREACH_SAFE(client_list_hdr, ptr, tmp)
    {
        n ++;
    }

    return n;
}
/**
 * @brief     更新客户端一个节点的值
 * @param [in]  
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
static uint32_t client_list_update(client_info_t *pclient, session_t cid)
{
    client_info_t *ptr = NULL;
    
    assert(client_list_hdr);
    assert(pclient);
    if((client_list_hdr == NULL) || (pclient == NULL))
    {
        // TODO:返回错误——参数错误
        return ERR_ARG;
    }
    // 查找符合条件的条目
    LL_SEARCH_SCALAR(client_list_hdr, ptr, id, cid);
    if(ptr)
    {
        MEMCPY(ptr, pclient, sizeof(client_info_t));
        return ERR_NULL;
    }
    else
    {
        return ERR_NOT_FOUND;
    }
}
/**
 * @brief     更新客户端一个节点的是否获取日志的值
 * @param [in]  
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
static uint32_t client_list_update_recv(session_t cid, bool flg)
{
    client_info_t *ptr = NULL;
    
    assert(client_list_hdr);
    if(client_list_hdr == NULL)
    {
        // TODO:返回错误——参数错误
        return ERR_ARG;
    }
    // 查找符合条件的条目
    LL_SEARCH_SCALAR(client_list_hdr, ptr, id, cid);
    if(ptr)
    {
        ptr->recv = flg;
        return ERR_NULL;
    }
    else
    {
        return ERR_NOT_FOUND;
    }
}
/**
 * @brief     更新客户端一个节点的是否获取日志的等级
 * @param [in]  
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
static uint32_t client_list_update_log_level(session_t cid, log_level_t lvl)
{
    client_info_t *ptr = NULL;
    
    assert(client_list_hdr);
    if(client_list_hdr == NULL)
    {
        // TODO:返回错误——参数错误
        return ERR_ARG;
    }
    // 查找符合条件的条目
    LL_SEARCH_SCALAR(client_list_hdr, ptr, id, cid);
    if(ptr)
    {
        ptr->lvl = lvl;
        return ERR_NULL;
    }
    else
    {
        return ERR_NOT_FOUND;
    }
}
/************************************************************************/
/* 日志模块                                                             */
/************************************************************************/
/**
 * @brief     复制函数
 * @param [in]  
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
static void log_queue_copy(void *_dst, const void *_src)
{
    assert(_dst);
    assert(_src);
    log_entry_t *dst = (log_entry_t*)_dst, *src = (log_entry_t*)_src;
    if(_dst && _src)
    {
        dst->_log = src->_log ? strdup(src->_log) : NULL;
        dst->_time = src->_time ? strdup(src->_time) : NULL;
        dst->_grp = src->_grp;
        dst->_lvl = src->_lvl;
    }
}
/**
 * @brief     释放函数
 * @param [in]  
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
static void log_queue_dtor(void *_elt) {
    assert(_elt);
    log_entry_t *elt = (log_entry_t*)_elt;
    if (elt->_log) 
    {
        free(elt->_log);
    }
    if (elt->_time) 
    {
        free(elt->_time);
    }
}

UT_icd log_entry_icd = {sizeof(log_entry_t), NULL, log_queue_copy, log_queue_dtor};

/**
 * @brief     将日志条目写入文件中并向客户端发送
 * @param [in] 日志条目
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
static void log_to_file(log_entry_t * plog)
{
    int i;
    client_info_t *el, *tmp;
    char buf[512];

    sprintf(buf, "%s(%s - %s): %s\n\0", plog->_time, GET_LOG_GROUP(plog->_grp),GET_LOG_LEVEL(plog->_lvl),
        plog->_log);
    if(plog->_lvl <= _log_lvl)
    {  
        fwrite(buf, strlen(buf), 1, log_fp);
        fflush(log_fp);
    }
    LL_FOREACH_SAFE(client_list_hdr, el, tmp)
    {
        // 需要日志，并且日志等级高于等于日志等级
        if((el->recv == true) && (plog->_lvl <= el->lvl))
        {
            send_task(ADDR_OUT, ADDR_LOG,
                el->session,
                TYP_LOG_ENTRY,
                DIR_NO_RESPONSE, el->session,
                strlen(buf), (unsigned char *)buf);
        }
    }
}
/**
 * @brief     组装一条日志
 * @param [in]  
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
static log_entry_t * log_assembly(enum log_group_t group, enum log_level_t level, log_entry_t * plog, int8_t *log_data)
{
    time_t rawtime;
    struct tm *timeinfo;
    char time_buff[256];

    assert(plog);
    assert(log_data);
    if(!plog || !log_data)
    {
        return NULL;
    }
    /*组装时间信息*/
    time(&rawtime);
    timeinfo = localtime(&rawtime);
    memset(time_buff, 0x00, sizeof(time_buff));
    sprintf(time_buff, "%d-%d-%d %d:%d:%d", timeinfo->tm_year + 1900,
        timeinfo->tm_mon + 1, timeinfo->tm_mday, timeinfo->tm_hour,
        timeinfo->tm_min, timeinfo->tm_sec);

    plog->_grp = group;
    plog->_lvl = level;
    strncpy(plog->_time, time_buff, min(sizeof(time_buff), sizeof(plog->_time)));
    strncpy(plog->_log, log_data, sizeof(plog->_log));
    return plog;
};
/**
 * @brief       一条新的日志
 * @param [in]  
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
void log_new(enum log_group_t group, enum log_level_t level, int8_t * log)
{
    log_entry_t entry;

    if(log_assembly(group, level, &entry, log))
    {
    pthread_mutex_lock(&log_mutex);
    utarray_push_back(log_queue, entry);
    pthread_mutex_unlock(&log_mutex);
    }
}
/**
 * @brief      日志模块的内部通讯处理
 * @param [in]  
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
static void task_log_handler(thrd_task_entry_t *ptask)
{
    switch(ptask->type)
    {
    case TYP_LOG_GET://远端要求发送日志
        client_list_update_recv(ptask->session, (ptask->data_buf[0] ? true:false ));
        break;
    case TYP_LOG_LEVEL://调整日志等级
        _log_level = (log_level_t)ptask->data_buf[0];
        break;
    case TYP_LOG_CLIENT_LEVEL://远端调整日志等级
        client_list_update_log_level(ptask->session, (log_level_t)ptask->data_buf[0]);
        break;
    default:
        break;
    }
}
/*
 *	@brief tcp管理服务器通讯线程——处理任务队列
 */
static void task_handler(thrd_task_entry_t *ptask)
{
    log_entry_t entry;
    int8_t log[256];
    switch(ptask->type)
    {
        /// 停止线程
    case TYP_THRD_STOP:
        switch(task.dir)
        {
        case DIR_REQUEST:
            break;
        case DIR_RESPONSE:
            break;
        case DIR_NO_RESPONSE:
            stop_flg = true;
            break;
        }
        break;
    case TYP_PROG_QUIT://程序退出
        switch(task.dir)
        {
        case DIR_REQUEST:
            break;
        case DIR_RESPONSE:
            break;
        case DIR_NO_RESPONSE:
            task.dst = ADDR_ALL;
            task.type = TYP_THRD_STOP;
            send_task_entry(&task);
            break;
        }
        break;
    /// 外部通讯模块
    case TYP_SERV_START:
    case TYP_SERV_NEW_CLIENT:
    case TYP_SERV_DEL_CLIENT:
        break;
    /// 日志模块
    case TYP_LOG_GET:
    case TYP_LOG_ENTRY:
    case TYP_LOG_LEVEL:
    case TYP_LOG_CLIENT_LEVEL:
        task_log_handler(ptask);
        break;
    default:
        MEMSET(log, 0, sizeof(log));
        snprintf(log, sizeof(log)-1, "%s(%s - %s)不支持的内部通讯类型%d（%s）",
            __FILE__, __LINE__, __FUNCTION__,
            ptask->type, TASK_TYPE_TO_STRING(ptask->type));
        if(log_assembly(LOG_GRP_SW, LOG_LVL_WARNING, &entry, log))
        break;
    }
}
/************************************************************************/
/* 内部通讯模块                                                         */
/************************************************************************/
/**
 * @brief     内部通讯模块-路由函数
 * @param [in]  
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
static int task_route(thrd_task_entry_t &task)
{
    int i = 0;
    thrd_task_t *ptask;
    thrd_ctl_list_node_t * ptr, *tmp;
    ctl_cmd_t cmd;
    bool flg = false;
    int32_t ret = 0;

    pthread_mutex_lock(&_thrd_info_mutex);
    if(task.ttl == 0)
    {
        //TODO：返回错误-丢弃太长时间没有发出去的数据包。
        ret = -1;
        goto RET;
    }
    for(i = 0;  (thrd_info[i].valid == true) && (i < thrd_num); i++)
    {
        // 查找线程
        if(thrd_info[i].addr == task.src)
        {
            thrd_info[i].num_out ++;//输出数据包计数+1
            break;
        }
    }
    if( i == thrd_num)
    {
        //TODO：返回错误-无效的源地址。
        ret = -1;
        goto RET;
    }
    task.ttl --;
    //cmd = ctl_cmd_t(task.data_buf[4] << 8 + task.data_buf[5]);
    for(i = 0; (thrd_info[i].valid == true) && (i < thrd_num); i++)
    {
        // 查找线程或者是广播通讯
        if((thrd_info[i].addr == task.dst) || (ADDR_ALL == task.dst))
        {
            thrd_info[i].num_in ++;//输入数据包计数+1
            if(thrd_info[i]._in != NULL)//线程有输入管道
            {
                //将通讯写入管道
                ptask = thrd_info[i]._in;
                {
                    boost::mutex::scoped_lock lock(ptask->_mutex);

                    ptask->_queue.push(task);
                    ptask->_cond.notify_one();
                    // 如果注册了条件变量
                    if(thrd_info[i]._in_cond != NULL)
                    {
                        thrd_info[i]._in_cond->notify_one();
                    }
                    flg = true;
                }
                
            }
            else
            {
                //TODO：返回错误-线程没有输入管道。
                ret = -2;
                goto RET;
            }
        }
        else if(ADDR_IN == task.dst)// 输入通讯
        {
            
            LL_FOREACH_SAFE(thrd_info[i].ctl_list_hdr, ptr, tmp)
            {
                if(ptr->cmd == task.type)
                {
                    thrd_info[i].num_in ++;//输入数据包计数+1
                    if(thrd_info[i]._in != NULL)//线程有输入管道
                    {
                        //将通讯写入管道
                        task.dst = (task_addr_t)thrd_info[i].addr;
                        ptask = thrd_info[i]._in;
                        {
                            boost::mutex::scoped_lock lock(ptask->_mutex);
                            ptask->_queue.push(task);
                            ptask->_cond.notify_one();
                            // 如果注册了条件变量
                            if(thrd_info[i]._in_cond != NULL)
                            {
                                thrd_info[i]._in_cond->notify_one();
                            }
                            flg = true;
                        }
                        
                    }
                    else
                    {
                        //TODO：返回错误-线程没有输入管道。
                        ret = -2;
                        goto RET;
                    }
                }
            }
        }
        else if((ADDR_OUT == task.dst) && (thrd_info[i].addr == ADDR_TCP))// 输出通讯
        {
            thrd_info[i].num_in ++;//输入数据包计数+1
            if(thrd_info[i]._in != NULL)//线程有输入管道
            {
                //将通讯写入管道
                ptask = thrd_info[i]._in;
                {
                    boost::mutex::scoped_lock lock(ptask->_mutex);
                    ptask->_queue.push(task);
                    ptask->_cond.notify_one();
                    // 如果注册了条件变量
                    if(thrd_info[i]._in_cond != NULL)
                    {
                        thrd_info[i]._in_cond->notify_one();
                    }
                    flg =true;
                }
                
            }
            else
            {
                //TODO：返回错误-线程没有输入管道。
                ret =  -2;
                goto RET;
            }
        }
    }
    // 没有找到目的线程
    if(flg == false)
    {
        //向交换线程的输入队列写入，重新进行交换
        pthread_mutex_lock(&_in_task._mutex);
        _in_task._queue.push(task);
        //_in_task._cond.notify_one();
    }
RET:
    pthread_mutex_unlock(&_thrd_info_mutex);
    return ret;
}
//static UINT timer_id = 10;
/*
 *	@brief 定时器回调函数
 */
//VOID CALLBACK on_timer( HWND, UINT, UINT, DWORD )
//{
//    //向交换线程的输入队列写入，重新进行交换
//    boost::mutex::scoped_lock lock(_in_task._mutex);
//    _in_task._cond.notify_one();
//    return ;
//}
/*
 * @brief 交换线程处理函数
 */
static void switch_thrd_routin()
{
    thrd_task_entry_t task;
  
    //SetTimer(NULL, timer_id, 1000, on_timer);
    /// 循环直到通知退出线程
    while(stop_flg == false)
    {
        {
            // 查询是否有等待处理的任务
            boost::mutex::scoped_lock lock(_in_task._mutex);
            if(_in_task._queue.size() <= 0 )
            {
                _in_task._cond.wait(lock);
                continue;
            }
            task = _in_task._queue.front();
            _in_task._queue.pop();
        }
        // 是不是发给交换线程的
        if(task.dst == ADDR_SWITCH)
        {
            task_handler(task);
        }
        else
        {
            task_route(task);
        }
    }
    //KillTimer(NULL, timer_id);
    logger_log(LOG_GRP_ALL, LOG_LVL_INFO, "远程管理通讯线程退出！！！");

}
/************************************************************************/
/* 模块信息维护                                                         */
/************************************************************************/
/**
 * @brief     添加一个新的客户端
 * @param [in]  
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
static uint32_t thrd_info_list_add(thrd_info_t *pinfo)
{
    thrd_info_t * ptr, *tmp;
    assert(pinfo);
    assert(thrd_info_hdr);

    if(!thrd_info_hdr || !pinfo)
    {
        return ERR_ARG;
    }

    ptr = (thrd_info_t *)CALLOC(1, sizeof(thrd_info_t));
    if(ptr == NULL)
    {
        // TODO:返回错误——分配内存错误
        return ERR_NO_MEM;
    }
    MEMCPY(ptr, pinfo, sizeof(thrd_info_t));
    LL_APPEND(thrd_info_hdr, ptr);

    return ERR_NULL;
}

/**
 * @brief     删除一个客户端
 * @param [in]  id:客户端ID
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
static void client_list_del(session_t id)
{
    client_info_t *ptr = NULL, *tmp = NULL;

    if(client_list_hdr == NULL)
    {
        // TODO:返回错误——参数错误
        return;
    }
    // 查找符合条件的条目并删除和释放
    LL_FOREACH_SAFE(client_list_hdr, ptr, tmp)
    {
        if(ptr->id == id)
        {
            LL_DELETE(client_list_hdr, ptr);
            FREE(ptr);
            break;
        }
    }

    return ;
}
/**
 * @brief     获取客户端
 * @param [in]  
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
static client_info_t *client_list_get(client_info_t *pclient, session_t cid)
{
    client_info_t *ptr = NULL, *tmp = NULL;

    if((client_list_hdr == NULL) || (pclient == NULL))
    {
        // TODO:返回错误——参数错误
        return NULL;
    }
    // 查找符合条件的条目
    LL_SEARCH_SCALAR(client_list_hdr, ptr, id, cid);
    if(ptr)
    {
        MEMCPY(pclient, ptr, sizeof(client_info_t));
        return pclient;
    }

    //LL_FOREACH_SAFE(client_list_hdr, ptr, tmp)
    //{
    //    if(ptr->id == id)
    //    {
    //        MEMCPY(pclient, ptr, sizeof(client_info_t));
    //        return pclient;
    //    }
    //}

    return NULL;
}
/**
 * @brief     获取客户端列表的长度
 * @param [in]  
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
static uint32_t client_list_len()
{
    int n =0;
    client_info_t *ptr = NULL, *tmp = NULL;

    // 查找符合条件的条目
    LL_FOREACH_SAFE(client_list_hdr, ptr, tmp)
    {
        n ++;
    }

    return n;
}
/**
 * @brief     更新客户端一个节点的值
 * @param [in]  
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
static uint32_t client_list_update(client_info_t *pclient, session_t cid)
{
    client_info_t *ptr = NULL;
    
    assert(client_list_hdr);
    assert(pclient);
    if((client_list_hdr == NULL) || (pclient == NULL))
    {
        // TODO:返回错误——参数错误
        return ERR_ARG;
    }
    // 查找符合条件的条目
    LL_SEARCH_SCALAR(client_list_hdr, ptr, id, cid);
    if(ptr)
    {
        MEMCPY(ptr, pclient, sizeof(client_info_t));
        return ERR_NULL;
    }
    else
    {
        return ERR_NOT_FOUND;
    }
}
/**
 * @brief     从名字得到地址
 * @param [in]  
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
task_addr_t addr_from_name(const char * name)
{
    assert(name);
    if(name)
    {
    return (task_addr_t)(name[0] << 24 | name[1] << 16 | name[2] << 8 | name[3]);
    }
    else
    {
        return ADDR_UNKONW;
    }
}
/*
*@brief 向交换线程注册本线程
*/
int register_thrd(const char *name, thrd_task_t *_in_queue, thrd_task_t *_out_queue, boost::condition_variable *cond)
{
    int i;
    if(name == NULL)
    {
        //TODO：返回错误-参数为空。
        return -1;
    }
    boost::mutex::scoped_lock lock(_thrd_info_mutex);
    for(i = 0; (thrd_info[i].valid == true) && (i < thrd_num); i++)
    {
        // 轮询是否有重名线程
        if(memcmp(thrd_info[i].name, name, 4) == 0)
        {
            //TODO：返回错误-有重名线程已经注册
            return -1;
        }
    }
    //添加线程信息
    memcpy(thrd_info[i].name, name, sizeof(thrd_info[i].name) - 1);
    thrd_info[i].addr = addr_from_name(name);
    thrd_info[i]._in = _in_queue;
    thrd_info[i]._out = _out_queue;
    thrd_info[i].valid = true;
    thrd_info[i]._in_cond = cond;
    thrd_num ++;
    char log[256];
    sprintf(log, "%s线程注册成功。地址为：%d、输入管道：%s、输出管道：%s",
            thrd_info[i].name, thrd_info[i].addr,
            (thrd_info[i]._in == NULL ? "无\0" : "有\0"),
            (thrd_info[i]._out == NULL ? "无\0" : "有\0"));

    logger_log(LOG_GRP_ALL, LOG_LVL_INFO, log, strlen(log));

    return 0;
}

/************************************************************************/
/* @brief 向交换线程注册本线程接受的命令                                */
/************************************************************************/
int register_thrd_ctl_cmd(const char *name, thrd_ctl_list_node_t * pnode)
{
    int i;
    thrd_ctl_list_node_t * ptr;
    if(name == NULL)
    {
        //TODO：返回错误-参数为空。
        return -1;
    }
    boost::mutex::scoped_lock lock(_thrd_info_mutex);
    for(i = 0; (thrd_info[i].valid == true) && (i < thrd_num); i++)
    {
        // 轮询是否有重名线程
        if(memcmp(thrd_info[i].name, name, 4) == 0)
        {
            ptr = (thrd_ctl_list_node_t *)CALLOC(1, sizeof(thrd_ctl_list_node_t));
            MEMCPY(ptr, pnode, sizeof(thrd_ctl_list_node_t));
            LL_APPEND(thrd_info[i].ctl_list_hdr, ptr);
            char log[256];
            sprintf(log, "%s线程添加命令=%d()",
                thrd_info[i].name, ptr->cmd, TASK_TYPE_TO_STRING(ptr->cmd));

            logger_log(LOG_GRP_ALL, LOG_LVL_INFO, log, strlen(log));
            break;
        }
    }


    return 0;    
}
//////////////////////////////////////////////////////////////////////////
//          通讯队列处理
//////////////////////////////////////////////////////////////////////////
/************************************************************************/
/* @brief 复制函数                                                      */
/************************************************************************/
void thrd_task_entry_copy(void *_dst, const void *_src)
{
    assert(_dst);
    assert(_src);
    thrd_task_entry_t *dst = (thrd_task_entry_t*)_dst, *src = (thrd_task_entry_t*)_src;
    if(_dst && _src)
    {
        dst->data_buf = src->data_buf ? strdup(src->data_buf) : NULL;
        dst->data_size = src->data_size;
        dst->dir = src->dir;
        dst->dst = src->dst;
        dst->seqno = src->seqno;
        dst->session = src->session;
        dst->src = src->src;
        dst->ttl = src->ttl;
        dst->type = src->type;
        dst->prio = src->prio;
        dst->delay = src->delay;
    }
}
/************************************************************************/
/* @brief 释放函数                                                      */
/************************************************************************/
void thrd_task_entry_dtor(void *_elt) {
    assert(_elt);
    thrd_task_entry_t *elt = (thrd_task_entry_t*)_elt;
    if (elt->data_buf) 
    {
        free(elt->data_buf);
    }
}

UT_icd thrd_task_entry_icd = {sizeof(thrd_task_entry_t), NULL, thrd_task_entry_copy, thrd_task_entry_dtor};
/**
 * @brief     内部通讯队列push函数
 * @param [in]  
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
static int32_t thrd_task_push(struct thrd_task * pcomm, thrd_task_entry_t * pentry)
{
    assert(pentry);
    assert(pcomm);
    utarray_push_back(pcomm, pentry);
    return (ERR_NULL);
}
/**
 * @brief     内部通讯队列pop函数
 * @param [in]  
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
static int32_t thrd_task_pop(struct thrd_task * pcomm, thrd_task_entry_t * pentry)
{
    assert(pentry);
    assert(pcomm);
    utarray_erase(pcomm, 0, 1);
    return (ERR_NULL);
}
/**
 * @brief     获取内部通讯队列长度
 * @param [in]  
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
static int32_t thrd_task_length(struct thrd_task * pcomm)
{
    assert(pcomm);
    return (utarray_len(pcomm));
}
/**
 * @brief     获取内部通讯队列第一个元素
 * @param [in]  
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
static thrd_task_entry_t * thrd_task_front(struct thrd_task * pcomm, thrd_task_entry_t * pentry)
{
    assert(pentry);
    assert(pcomm);
    pentry = utarray_front(pcomm);
    return (pentry);
}
/**
 * @brief     内部通讯队列初始化函数
 * @param [in]  
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
thrd_task_t * thrd_task_init(thrd_task_t * pcomm)
{
    assert(pcomm);
    pcomm->front = thrd_task_front;
    pcomm->length = thrd_task_length;
    pcomm->pop = thrd_task_pop;
    pcomm->push = thrd_task_push;
    pthread_mutex_init(&pcomm->_mutex, NULL);
    pthread_cond_init(&pcomm->_cond, NULL);
    utarray_new(pcomm->_queue, &thrd_task_entry_icd);
}
/**
 * @brief     内部通讯队列释放函数
 * @param [in]  
 * @param [in]  
 * @param [out] 
 * @return     
 *	
 */
void thrd_task_free(thrd_task_t * pcomm)
{
    assert(pcomm);
    utarray_free(pcomm);
    pthread_mutex_destroy(&pcomm->_mutex);
    pthread_cond_destroy(&pcomm->_cond);
}
/*
 *	@brief 准备并发送内部通讯
 */
int send_task(
    unsigned int dst,                       // 目的线程
    unsigned int src,                       // 源线程
    unsigned int session,                   // 会话ID，可以用于表示一个会话
    task_type_t type,                       // 任务类型
    task_dir_t dir,                         // 任务方向
    unsigned int seqno,                     // 序列号，回复的序列号必须和请求的序列号相同
    unsigned int data_size,                 // 携带的数据长度
    unsigned char*  data_buf                 // 数据区
)
{
    thrd_task_entry_t task;

    task.dst = (task_addr_t)dst;
    task.src = (task_addr_t)src;
    task.session = session;
    task.type = type;
    task.dir = dir;
    task.seqno = seqno;
    task.ttl = TASK_TTL_MAX;
    task.data_size = data_size;
    if(data_size > sizeof(task.data_buf))
    {
        //TODO：返回错误-数据长度超过缓冲区长度
        return -1;
    }
    memcpy((void *)task.data_buf, (void *)data_buf, data_size);
    
    //向交换线程的输入队列写入
    send_task_entry(&task);
    return 0;
}
/*
 *	
 */
/*
 *	@brief 准备并发送内部通讯
 */
int send_task_entry(thrd_task_entry_t *ptask)
{
    ptask->ttl = TASK_TTL_MAX;
    
    //向交换线程的输入队列写入
    boost::mutex::scoped_lock lock(_in_task._mutex);
    _in_task._queue.push(*ptask);
    _in_task._cond.notify_one();
    return 0;
}
/*
 *	@brief 启动交换线程
 */
int switch_start()
{
    memset((void *) thrd_info, 0x00, sizeof(thrd_info));
    thrd_num = 0;
    MEMSET((void *) &_in_task, 0, sizeof(_in_task));
    pthread_mutex_init(&_in_task._mutex, NULL)
    pthread_create(&tid, NULL, switch_thrd_routin, NULL);
    return 0;
}

/*
 *	@brief 停止服务线程
 */
void switch_stop()
{
    
}
